package ThreadPool.test;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @param
 * @author oyz
 * @version 1.0.4
 * @description: 利用Condition来实现三个线程交叉打印 a,b,c
 * @date 2022/9/3 12:33
 */
public class ThreadTest1_2 {


    private static ReentrantLock  lock = new ReentrantLock();

    private static int num = 1;

    public static void main(String[] args) {
        //testThread();
        Condition a = lock.newCondition();
        Condition b = lock.newCondition();
        Condition c = lock.newCondition();
        Thread t1 = new Thread(new MyRuable(lock,a,b,"a",34));
        Thread t2 = new Thread(new MyRuable(lock,b,c,"b",33));
        Thread t3 = new Thread(new MyRuable(lock,c,a,"c",33));
        t1.start();
        t2.start();
        t3.start();


    }

    public static void testThread(){
        Condition a = lock.newCondition();
        Condition b = lock.newCondition();
        Condition c = lock.newCondition();
        new Thread(()->{
            while(true){
                lock.lock();
                try {
                    if(num<=100) {
                        System.out.println("a");
                        num++;
                        b.signal();
                        a.await();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    lock.unlock();
                }
            }
        }).start();
        new Thread(()->{
            for(;;){
                lock.lock();
                try{
                    if(num<=100){
                        System.out.println("b");
                        num++;
                        c.signal();
                        b.await();
                    }
                }catch (InterruptedException e){
                    e.printStackTrace();
                }finally {
                    lock.unlock();
                }
            }
        }).start();
        new Thread(()->{
            for(;;){
                lock.lock();
                try{
                    if(num<=100){
                        System.out.println("c");
                        num++;
                        a.signal();
                        c.await();
                    }
                }catch (InterruptedException e){
                    e.printStackTrace();
                }finally {
                    lock.unlock();
                }
            }
        }).start();

    }

}



    /**
     * @description: 公共方法,把上边的方法抽象出来
     * @author oyz
     * @param
     * @date 2022/9/3 15:59
     * @version 1.0
     */
     class MyRuable implements Runnable{


         // 当前锁
        private ReentrantLock lock ;

        // 当前条件
        private Condition currentCondition;

        // 下一个条件
        private Condition nextCondition;


        // 打印到的字符位置
        private Integer index = 0;

        // 打印字符串
        private String character;

        // 打印总数
        private int numbers;

        public MyRuable(ReentrantLock lock, Condition currentCondition, Condition nextCondition,String character,int numsbers) {
            this.lock = lock;
            this.currentCondition = currentCondition;
            this.nextCondition = nextCondition;
            this.character = character;
            this.numbers = numsbers;
        }



        @Override
        public void run() {
            for (;;){
                lock.lock();
                try{
                    if(index <= numbers){
                        System.out.println(character);
                        index++;
                        nextCondition.signal();
                        currentCondition.await();
                    }

                }catch (InterruptedException e){
                    e.printStackTrace();
                }finally{
                    lock.unlock();
                }

            }
        }
    }